package com.echo.boot.aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;

/**
 * Created with IntelliJ IDEA
 * Created By CQ
 * Date: 2020/4/4
 * Time: 13:51
 */

@Aspect
@Component
@EnableAspectJAutoProxy
public class WebLogAspect {
    // 执行顺序
    // 前置通知，环绕通知前，
    private Logger logger = LoggerFactory.getLogger(getClass());

    @Pointcut("execution( * com.echo.boot.controller.FreemarkeController.*(..))")
    public void logPointCut() {
    }


    /**
     * @author CQ
     * @DESCRIPTION: 前置通知
     * @params: [joinPoint]
     * @return: void
     * @Date: 2020/7/2 19:34
     * @Modified By:
     */
    @Before("logPointCut()")
    public void doBefore(JoinPoint joinPoint) throws Throwable {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        logger.info("URL : " + request.getRequestURL().toString());
        logger.info("HTTP_METHOD : " + request.getMethod());
        logger.info("IP : " + request.getRemoteAddr());
        logger.info("CLASS_METHOD :" + request.getMethod());
        logger.info("ARGS  : " + Arrays.toString(joinPoint.getArgs()));
        logger.info("doBefor -> SignatureName : " + joinPoint.getSignature().getName());
    }

    /**
     * @author CQ
     * @DESCRIPTION: 返回后通知： 执行方法结束前执行(异常不执行)
     * @params: [joinPoint, ret]
     * @return: void
     * @Date: 2020/7/2 19:36
     * @Modified By:
     */
    @AfterReturning(returning = "ret", pointcut = "logPointCut()")
    // 返回后通知： 执行方法结束前执行(异常不执行)
    public void doAfterReturning(JoinPoint joinPoint, Object ret) {
        logger.info("doAfterReturning -> SignatureName  : " + joinPoint.getSignature().getName());
        logger.info("Response : " + ret);
    }

    /**
     @After("logPointCut()") public void doAfter() {
     // 最终通知
     System.out.println("后置通知：目标方法之后执行（始终执行）");
     }


     @Around("logPointCut()") public void doAround(ProceedingJoinPoint joinPoint) throws Throwable {
     System.out.println("环绕通知： 环绕目标方法执行");
     System.out.println("环绕通知：-前");
     joinPoint.proceed();
     //环绕通知 在抛出异常以下不会执行
     // 如果异常被try  catch 以下还是会执行
     System.out.println("环绕通知：-后");
     }

     @AfterThrowing("logPointCut()") public void doAfterThrowing(JoinPoint joinPoint) {
     //异常通知:  出现异常时候执行
     joinPoint.getSignature().getName();
     System.out.println("异常通知:  出现异常时候执行");
     }
     */
}
